<!-- 对话模型 -->

<template>
  <div class="dialogue">
    <div v-if="chatCurrentList.length > 0"
      :style="{ height: props.interData.is_audio === '1' ? 'calc(100vh - 270px)' : 'calc(100vh - 200px)' }"
      ref="chatMainMessagesRef" class="chat-main-messages">
      <!-- <FlexScroll ref="chatMainMessagesRef" :disabled="pagination.page >= pageCount" @scroll="nextPage"
        :immediate="immediate"> -->
      <div class="flex-msg" v-for="(item, index) in chatCurrentList" :key="index">
        <!-- <img class="avatar"
          :src="item.chatType === 'bot' ? props.interData.avatar : user?.avatar ? user.avatar : AdminIcon" alt=""> -->
        <Avatar :avatar="item.chatType === 'bot' ? props.interData.avatar : user.avatar" :icon-size="38"
          :class-name="'avatar-image'" />
        <div :class="{
      'user-message': item.chatType === 'user',
      'bot-message': item.chatType === 'bot'
    }">
          <div class="info">
            <div class="ai_loading" v-if="item.chatType === 'bot' && item.message === ''" />
            <div v-if="item.chatType === 'user'">{{ item.message }}</div>
            <div class="chat-bot" v-else v-html="getMdiText(item.message)" />
          </div>
        </div>
      </div>
      <!-- </FlexScroll> -->
    </div>
    <el-empty v-else description="暂无数据" class="chat-main-messages"
      :style="{ height: props.interData.is_audio === '1' ? 'calc(100vh - 270px)' : 'calc(100vh - 200px)' }" />

    <!-- <audio ref="audio" controls @play="playNextTrack" src="https://engine-robot.lnkyeah.com/static/155c2631dd7c49a648922213deaca1ed.mp3" />  -->
    <div class="audio-bottom" v-if="props.interData.is_audio === '1'">
      <audio ref="audioPlayer" :src="voiceQueueUrls[0]" @play="playNextTrack" autoplay controls />
    </div>
    <div class="dialogue-ipt">
      <img :src="arrowIcon1" alt="" srcset="" />
      <el-input v-model="userMessage" class="d-input" placeholder="请输入" @keydown.enter="handleMessageEnter">
        <template #suffix>
          <el-icon class="el-input__icon" @click="handleMessageEnter">
            <img :src="arrowIcon" alt="" srcset="" />
          </el-icon>
        </template>
      </el-input>
      <img :src="arrowIcon2" alt="" srcset="" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { RobotListProps } from "@/api/cloud/types/cloud"
import arrowIcon from "@/assets/docs/arrow_icon.svg"
import arrowIcon1 from "@/assets/docs/arrow_icon_1.svg"
import arrowIcon2 from "@/assets/docs/arrow_icon_2.svg"
import Avatar from "@/components/Avatar/index.vue"
import useMarkdown from "@/hooks/useMarkdown/useMarkdown"
import { useUserStore } from "@/store/modules/user"
import playVoice from "@/utils/playVoice"
import Speech from "@/utils/speech"
import { ElMessage } from "element-plus"
import { storeToRefs } from "pinia"
import { nextTick, onMounted, ref } from "vue"
import useChat from "../useChat"

interface InterDataProps {
  interData: RobotListProps
}

const { getMdiText } = useMarkdown()

const URL = new URLSearchParams(window.location.search);
const robotId = URL.get('id');

const {
  userMessage,
  chatMainMessagesRef,
  chatBoolTextEnd,
  chatCurrentList,
  handleScrollToBottom,
  initChatList,
  handleMessageEnter,
} = useChat(robotId)

const userStore = useUserStore()
const { user } = storeToRefs(userStore)
const audioPlayer = ref<HTMLAudioElement>()
const props = defineProps<InterDataProps>()
// 存储待播放的 URL 队列
const voiceQueueUrls = ref<string[]>([""])
const isPlaying = ref<boolean>(false)

const playNextTrack = async () => {
  const audioQueueElement = audioPlayer.value as HTMLAudioElement
  if (voiceQueueUrls.value.length <= 0) {
    audioQueueElement.pause()
    audioQueueElement.currentTime = 0
    voiceQueueUrls.value = [""]
    return
  }

  if (!isPlaying.value) {
    isPlaying.value = true;
    audioQueueElement.onended = () => {
      voiceQueueUrls.value.shift() // 移除数组第一项
      isPlaying.value = false;
      playNextTrack() // 调用自身
    }
  }
}

onMounted(() => {
  // Speech.instance.init();
  initChatList()

  Speech.instance.on("chat_text", (msg: any) => {
    insertGptToAllData(msg)
  })

  Speech.instance.on("chat_text_end", (msg: any) => {
    console.log("文本结束 :>> ", msg)
    // chatBoolTextEnd.value = false;
  })

  Speech.instance.on("chat_audio", (msg: any) => {
    console.log("socket语音返回 :>> ", msg.url)
    if (msg && msg.url) {
      playVoice.instance.play(msg.url)
      voiceQueueUrls.value = playVoice.instance.getAudioQueue()
    }
  })

  Speech.instance.on("chat_audio_end", (msg: any) => {
    console.log("语音url回调结束 :>> ", msg)
    chatBoolTextEnd.value = false
  })
  nextTick(handleScrollToBottom)
  // @ts-ignore
  window.copyCode = copyCode
})

function copyCode(copyButton: any) {
  const codeBlock = copyButton.parentNode.nextSibling.querySelector("code")
  const codeText = codeBlock.innerText

  // 生成文本域，用于装饰代码块
  const textareaDom = document.createElement("textarea")
  textareaDom.value = codeText
  document.body.appendChild(textareaDom)
  textareaDom.select()
  document.execCommand("copy")
  ElMessage({
    type: "success",
    message: "复制成功"
  })
  document.body.removeChild(textareaDom)
}

// 将bot返回的数据插入到总聊天数据中
function insertGptToAllData(message: any) {
  let _allData = JSON.parse(JSON.stringify(chatCurrentList.value))
  let lastMsg = _allData[_allData.length - 1]
  if (lastMsg.chatType === "bot") {
    lastMsg.message += message.text
  } else {
    lastMsg = [{ chatType: "bot", message }]
  }
  saveChatDataToLocal(_allData)
  handleScrollToBottom()
}

// 将聊天记录保存到本地
const saveChatDataToLocal = (list: any) => {
  let res
  if (list.length > 300) {
    res = list.slice(-300)
  } else {
    res = list
  }
  chatCurrentList.value = res
}
</script>

<style lang="scss" scoped>
@import url("../../../hooks/useMarkdown/chat.scss");

.dialogue {
  width: 100%;
  height: 100%;

  img {
    cursor: pointer;
  }

  .audio-bottom {
    width: 100%;
    margin-bottom: 24px;

    audio {
      width: 100%;
    }
  }

  &-ipt {
    flex-shrink: 0;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .d-input {
      margin: 0 10px;
    }
  }

  ::v-deep .avatar_icon_img {
    .avatar-image {
      border-radius: 50%;
      margin-right: 10px;
      flex-shrink: 0;
    }
  }

  .chat-main-messages {
    width: 100%;
    /* flex-shrink: 0; */
    /* height: 100%; */
    height: calc(100vh - 220px);
    overflow-y: scroll;
    overflow-x: hidden;

    .flex-msg {
      position: relative;
      display: flex;
      flex-wrap: wrap;
      justify-content: flex-start;
      /* align-items: flex-end; */
      margin: 17px 10px 30px;

      &:last-child {
        margin-bottom: 40px;
      }

      &:first-child {
        margin-top: unset;
      }
    }

    &::-webkit-scrollbar {
      display: none;
    }

    .user-message,
    .bot-message {
      color: #333 !important;
      flex: 1;

      .info {
        position: relative;
        display: inline-block;
        padding: 10px 20px;
        gap: 10px;
        color: #333 !important;
        font-size: 14px;
        border-radius: 20px 20px 20px 5px;
        background: var(--v3-body-bg-color);
        line-height: 25px;

        ::v-deep p {
          display: inline;
        }
      }
    }

    .ai_loading {
      /* position: absolute;
      top: -10px;
      left: 0;
      font-size: 24px;
      padding: 5px 18px;
      display: flex;
      justify-content: center;
      align-items: center;
      background: var(--v3-body-bg-color);
      border-radius: 10px;
      overflow: hidden;
      white-space: nowrap; */

      &::after {
        content: "...";
        margin-bottom: 10px;
        animation: ellipsis 1.2s infinite;
      }

      @keyframes ellipsis {

        0%,
        100% {
          content: "...";
        }

        33% {
          content: ".. ";
        }

        66% {
          content: ".  ";
        }
      }
    }
  }
}
</style>
